import pygame
from pygame.locals import *
import math
import random
from badguy import Badguy
from weapon import Weapon
from mine import Mine
# 2
# 初始化pygame,创建了一个窗口
pygame.init()
width, height = 900, 480
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("兔子和獾")
keys = [False, False, False, False]
playerpos = [100, screen.get_rect().centery]
killNum = 0
arrows = []
# 定义一个定时器，使得游戏里可以经过一段时间后就新建一只獾
badtimer = 100
badtimer1 = 0

# 定义游戏时间
playTime = 120000
#定义武器数量
WeaponGroup = pygame.sprite.Group()
isDoubleArrow = False
# 生成双箭武器
doubleArrow = pygame.image.load("resources/images/bulletDouble.png")
doubleArrowX, doubleArrowY = random.randint(200, width//2), random.randint(20, height-20)
doubleArrowRect = pygame.Rect(doubleArrow.get_rect())
doubleArrowRect.top = doubleArrowY
doubleArrowRect.left = doubleArrowX

rada = 0
popTime = 2  # 定义一次消灭敌人的个数，否则会因为快速循环删除很多敌人
# badguys 记录badguy的位置坐标的列表

badguy1 = Badguy((900, 100))
BadguyGroup = pygame.sprite.Group()
BadguyGroup.add(badguy1)
badNum = 0
Badspeed = 1
BadMidBoss = 5
BadBigBoss = 1
hasKilledBigBoss = False
BossHasReached = False

healthvalue = 194
pygame.mixer.init()

isOutofWindow = False
# 3
# 加载本地图片
player = pygame.image.load("resources/images/dude.png")
grass = pygame.image.load("resources/images/grass.png")
castle = pygame.image.load("resources/images/castle.png")
arrow = pygame.image.load("resources/images/bullet.png")
# 加载武器图片
radaCursorImg = pygame.image.load("resources/images/radaCursor.png").convert_alpha()
radaImg = pygame.image.load("resources/images/rada.png")
# 加载獾图片
badguyimg1 = pygame.image.load("resources/images/badguy.png")
badguyimg = badguyimg1
# 加载健康图片
healthbar = pygame.image.load("resources/images/healthbar.png")
health = pygame.image.load("resources/images/health.png")
# 加载输赢图片
gameover = pygame.image.load("resources/images/gameover.png")
youwin = pygame.image.load("resources/images/youwin.png")
# 加载声音
hit = pygame.mixer.Sound("resources/audio/explode.wav")
enemy = pygame.mixer.Sound("resources/audio/enemy.wav")
shoot = pygame.mixer.Sound("resources/audio/shoot.wav")
hit.set_volume(0.05)
enemy.set_volume(0.05)
shoot.set_volume(0.05)
pygame.mixer.music.load('resources/audio/moonlight.wav')
pygame.mixer.music.play(-1, 0.0)
pygame.mixer.music.set_volume(0.25)

# 生成地雷
hasSteppedMine = False
minesPositions = [[random.randint(200, width-20), random.randint(20, height-20)] for i in range(5)]
MineGroup = pygame.sprite.Group()
for mineposition in minesPositions:
    mine = Mine(mineposition)
    MineGroup.add(mine)
# print(minesPositions)
time = 10
# 4
# 进入循环
running = 1
exitcode = 0
while running:
    badtimer -= 1
    badspeed = Badspeed  # 重新初始化坏蛋速度
    # 5 设置黑色背景
    screen.fill(0)

    # 6
    # 循环画上背景
    for x in range(width // grass.get_width() + 1):
        for y in range(height // grass.get_height() + 1):
            screen.blit(grass, (x * 100, y * 100))
            # 画上四个城堡
    screen.blit(castle, (0, 30))
    screen.blit(castle, (0, 135))
    screen.blit(castle, (0, 240))
    screen.blit(castle, (0, 345))

    # 画上小兔子
    # 玩家旋转兔子
    position = pygame.mouse.get_pos()
    angle = math.atan2(position[1] - (playerpos[1] + 32), position[0] - (playerpos[0] + 26))
    playerrot = pygame.transform.rotate(player, 360 - angle * 57.29)
    playerpos1 = (playerpos[0] - playerrot.get_rect().width // 2, playerpos[1] - playerrot.get_rect().height // 2)
    screen.blit(playerrot, playerpos1)

    playerrect = pygame.Rect(player.get_rect())
    playerrect.top = playerpos1[1]
    playerrect.left = playerpos1[0]

    # 双箭武器升级
    if killNum >= 20 and not isDoubleArrow:
        screen.blit(doubleArrow, (doubleArrowX, doubleArrowY))
        if doubleArrowRect.colliderect(playerrect):
            isDoubleArrow = True

    # 触碰雷区
    for mine in MineGroup.sprites():
        if mine.rect.colliderect(playerrect):
            hasSteppedMine = True
            break
    if hasSteppedMine:
        while time > 0:
            for mine in MineGroup.sprites():
                mine.show()
                screen.blit(mine.image, mine.rect, (mine.frame_no * mine.show_size_x, 0, mine.show_size_x, mine.show_size_y))
                pygame.display.update(mine.rect)
                time -= 1

    # 画出箭头
    for bullet in WeaponGroup.sprites():
        index = 0
        velx = math.cos(bullet.vex[0]) * 10
        vely = math.sin(bullet.vex[0]) * 10
        bullet.vex[1] += velx
        bullet.vex[2] += vely
        if bullet.vex[1] < -64 or bullet.vex[1] > 900 or bullet.vex[2] < -64 or bullet.vex[2] > 480:
            WeaponGroup.remove(bullet)
        index += 1
        for projectile in WeaponGroup.sprites():
            arrow1 = pygame.transform.rotate(bullet.image, 360 - projectile.vex[0] * 57.29)
            screen.blit(arrow1, (projectile.vex[1], projectile.vex[2]))
    # 画上獾

    if badtimer == 0:
        if BadBigBoss > 0:
            n = random.randint(0, 30)
            if n == 2 or n == 3:
                badspeed = n
            badguy = Badguy([900, random.randint(50, 430)], speed=badspeed)
            BadguyGroup.add(badguy)
            badNum += 1
        if killNum > 80 and BadMidBoss > 0:   # 杀死50个敌人 会出现5个中boss
            MidBoss = Badguy([900, random.randint(50, 430)], speed=0.8, health=30, scale=2)
            BadguyGroup.add(MidBoss)
            BadMidBoss -= 1
            badNum += 1
        if killNum > 120 and BadBigBoss > 0:  # 杀死80个敌人 会出现1个大boss
            BigBoss = Badguy([900, random.randint(50, 430)], speed=0.5, health=100, scale=3)
            BadguyGroup.add(BigBoss)
            BadBigBoss -= 1
            badNum += 1
        badtimer = 100 - (badtimer1 * 2)
        if badtimer1 >= 35:
            badtimer1 = 35
        else:
            badtimer1 += 2

    index = 0
    for badguy in BadguyGroup.sprites():
        if badguy.rect.left < -64:
            BadguyGroup.remove(badguy)
        badguy.move()
        # print(badguy.rect.left, badguy.rect.top)
        # 獾冲过来并且在碰到城堡的时候会消失。尽管你看不到，獾实际上会降低你的健康值。
        badrect = pygame.Rect(badguyimg.get_rect())
        badrect.top = badguy.rect.top
        badrect.left = badguy.rect.left
        if badrect.left < 64:
            hit.play()
            hitvalue = random.randint(1 * int((badguy.speed**2 + 1)), 3 * int((badguy.speed**2+1))) * badguy.health
            healthvalue -= hitvalue
            print(hitvalue)
            BadguyGroup.remove(badguy)
            try:
                if badguy is BigBoss:
                    BossHasReached = True
            except:
                pass
        # 检查箭头
        index1 = 0
        for bullet in WeaponGroup.sprites():
            bullrect = pygame.Rect(bullet.image.get_rect())
            bullrect.left = bullet.vex[1]
            bullrect.top = bullet.vex[2]
            # 检测箭头是否与坏蛋相交
            if badrect.colliderect(bullrect):
                badguy.health -= bullet.hit

                if badguy.health <= 0:
                    enemy.play()
                    killNum += 1
                    try:
                        if badguy == BigBoss:
                            hasKilledBigBoss = True
                            break
                    except:
                        pass
                    if killNum > 0 and killNum % 30 == 0:  # 杀死20个敌人获得一个雷达武器
                        rada += 1
                        popTime += 2
                    try:
                        BadguyGroup.remove(badguy)
                    except:
                        pass
                try:
                    WeaponGroup.remove(bullet)
                except:
                    pass
            index1 += 1
        index += 1
        screen.blit(badguy.image, badguy.rect)

    # 添加时钟用来计时
    font = pygame.font.Font(None, 24)
    survivedtext = font.render("endTime" + str((playTime - pygame.time.get_ticks()) // 60000) + "min:" + str((playTime - pygame.time.get_ticks()) // 1000 % 60).zfill(
        2), True, (0, 0, 0))
    textRect = survivedtext.get_rect()
    textRect.topright = [width-30, 5]
    screen.blit(survivedtext, textRect)


    # 显示已杀死的敌人
    font = pygame.font.Font(None, 24)
    killedtext = font.render("killed" + str(killNum) + "enemies" .zfill(
        2), True, (0, 0, 0))
    textRect = killedtext.get_rect()
    textRect.topright = [2*width//3, 5]
    screen.blit(killedtext, textRect)

    # 添加生命值显示
    screen.blit(healthbar, (5, 5))
    for health1 in range(healthvalue):
        screen.blit(health, (health1 + 8, 8))

    if rada > 0:
        screen.blit(radaImg, (200, 3))

    # 7
    # 刷新屏幕
    pygame.display.flip()

    # 8设置游戏退出条件
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()

    # 定义玩家wasd四个按键用来控制方向
        if playerpos[0] > width - 10 or playerpos[0] < 10 or playerpos[1] < 10 or playerpos[1] > height-10:
            isOutofWindow = True
        if event.type == pygame.KEYDOWN and not isOutofWindow:
            if event.key == K_w:
                keys[0] = True
            elif event.key == K_a:
                keys[1] = True
            elif event.key == K_s:
                keys[2] = True
            elif event.key == K_d:
                keys[3] = True

            if keys[0] and playerpos[1] > 10:
                playerpos[1] -= 10
            elif keys[2] and playerpos[1] < height - 10:
                playerpos[1] += 10
            elif keys[1] and playerpos[0] > 10:
                playerpos[0] -= 10
            elif keys[3] and playerpos[0] < width - 10:
                playerpos[0] += 10

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_w:
                keys[0] = False
            elif event.key == pygame.K_a:
                keys[1] = False
            elif event.key == pygame.K_s:
                keys[2] = False
            elif event.key == pygame.K_d:
                keys[3] = False


    # 雷达武器 一次消灭2个敌人，
    if event.type == pygame.KEYDOWN:
        if event.key == K_f and rada > 0:
            rada -= 1
            indx_1 = random.randint(0, len(BadguyGroup.sprites()))
            indx_2 = random.randint(0, len(BadguyGroup.sprites()))
    if event.type == pygame.KEYUP:
        if event.key == K_f and popTime > 0:
            try:
                # BadguyGroup.remove(BadguyGroup.sprites()[indx_1])
                # BadguyGroup.remove(BadguyGroup.sprites()[indx_2])
                BadguyGroup.sprites()[indx_1].health -= 1
                BadguyGroup.sprites()[indx_2].health -= 1
                if BadguyGroup.sprites()[indx_1].health <= 0:
                    BadguyGroup.remove(BadguyGroup.sprites()[indx_1])
                    killNum += 1
                if BadguyGroup.sprites()[indx_2].health <= 0:
                    BadguyGroup.remove(BadguyGroup.sprites()[indx_2])
                    killNum += 1
                popTime -= 2
            except:
                pass

    # 跟踪箭头
    if event.type == pygame.MOUSEBUTTONDOWN:
        shoot.play()
        position = pygame.mouse.get_pos()
        vex = [math.atan2(position[1] - (playerpos1[1] + 32),
                          position[0] - (playerpos1[0] + 26)),
               playerpos1[0] + 32,
               playerpos1[1] + 32
               ]
        # 装填武器
        if killNum < 20 or not isDoubleArrow:
            bullet = Weapon(vex=vex)
        elif isDoubleArrow:  # 双箭
            bullet = Weapon(filename="resources/images/bulletDouble.png", vex=vex, hit=2, channel=2)
        WeaponGroup.add(bullet)


    # 检查输赢
    if pygame.time.get_ticks() >= playTime or killNum >= 200 or hasKilledBigBoss:
        running = 0
        exitcode = 1
    if healthvalue <= 0 or BossHasReached or hasSteppedMine:
        running = 0
        exitcode = 0


        # 输赢显示
if exitcode == 0:
    pygame.time.wait(500)
    pygame.font.init()
    font = pygame.font.Font(None, 36)
    text = font.render("you have killed: " + str(killNum) + "enemies", True, (255, 0, 0))
    textRect = text.get_rect()

    gameover = pygame.transform.scale(gameover, (width, height))

    textRect.centerx = screen.get_rect().centerx
    textRect.centery = screen.get_rect().centery + 40
    screen.blit(gameover, (0, 0))
    screen.blit(text, textRect)
else:
    pygame.time.wait(1000)
    pygame.font.init()

    font = pygame.font.Font(None, 36)
    text = font.render("you have killed: " + str(killNum) + "enemies", True, (0, 255, 0))
    textRect = text.get_rect()

    youwin = pygame.transform.scale(youwin, (width, height))
    textRect.centerx = screen.get_rect().centerx
    textRect.centery = screen.get_rect().centery + 50
    screen.blit(youwin, (0, 0))
    screen.blit(text, textRect)
    if hasKilledBigBoss:
        text1 = font.render("you have killed the BigBoss! ", True, (0, 255, 0))
        textRect1 = text1.get_rect()
        textRect1.centerx = screen.get_rect().centerx
        textRect1.centery = screen.get_rect().centery + 20
        screen.blit(text1, textRect1)
while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit(0)
    pygame.display.flip()
